<template>
  <view class="form">
    <slot></slot>
  </view>
</template>

<script>
import Schema from "async-validator";

// 去除警告信息
Schema.warning = function () {};

export default {
  props: {
    model: {
      type: Object,
      default: () => {},
    },
    rules: {
      type: Object,
      default: () => {},
    },
  },
  data() {
    return {
      formItemProps: [],
      error: {},
    };
  },
  computed: {
    formRules() {
      return this.rules;
    },
    formModel() {
      return this.model;
    },
  },
  provide() {
    return {
      getFormItemProp: this.getFormItemProp,
      error: this.error,
    };
  },
  methods: {
    getFormItemProp(prop) {
      this.formItemProps.push(prop);
    },
    async validate(callback) {
      // 对所有带有prop属性的formItem组件进行校验
      let isValidatePass = true;
      for (let i = 0; i < this.formItemProps.length; i++) {
        const prop = this.formItemProps[i];
        try {
          await this.validateItem(prop);
        } catch (error) {
          isValidatePass = false;
        }
      }
      if (isValidatePass) {
        //校验通过
        callback(true);
      } else {
        callback(false);
      }
    },
    async validateItem(prop) {
      return new Promise(async (resolve, reject) => {
        let validateCount = 0;
        const propRulesLength = this.formRules[prop].length;
        for (let k = 0; k < propRulesLength; k++) {
          const validator = new Schema({
            [prop]: this.formRules[prop][k],
          });
          try {
            // 校验
            await validator.validate({
              [prop]: this.formModel[prop],
            });
            if (prop in this.error.value) {
              delete this.error.value[prop];
            }
            validateCount++;
          } catch (err) {
            // 提示错误消息
            this.error.value[prop] = err.errors[0].message;
            break;
          }
        }
        if (validateCount === propRulesLength) {
          console.log(validateCount, propRulesLength)
          resolve(null);
        } else {
          reject();
        }
      });
    },
  },
  // expose: {
  //   validate: this.validate,
  // },
};
</script>